package util.tools.gas;

public class GasLaws {

    public static double R = 0.0820574614; /*L atm / k mol*/

    private static double combined(GasData values, GasData values2) {
        double[] set1 = values.getValues(), set2 = values2.getValues();
        int one = getUnknown(set1);
        int two = getUnknown(set2);
        if (one != -1 && two == -1) {
            if (one == 0)
                return calculate(set2) * set1[2] / set1[1];
            else if (one == 1)
                return calculate(set2) * set1[2] / set1[0];
            else
                return 1 / calculate(set2) * set1[1] * set1[0];
        } else if (two != -1 && one == -1) {
            if (two == 0)
                return calculate(set1) * set2[2] / set2[1];
            else if (two == 1)
                return calculate(set1) * set2[2] / set2[0];
            else
                return 1 / calculate(set1) * set2[1] * set2[0];
        }
        return Double.NEGATIVE_INFINITY;
    }

    public static double boyles(GasData values) {
        double[] set = values.getValues();
        int i = values.getMissing();

        switch (i) {
            case 0:
                return set[2] * set[3] / set[1];
            case 1:
                return set[2] * set[3] / set[0];
            case 2:
                return set[0] * set[1] / set[3];
            case 3:
                return set[0] * set[1] / set[2];
        }
        return -1;
    }

    public static double charlesGay(GasData values) {
        double[] set = values.getValues();
        int i = values.getMissing();

        switch (i) {
            case 0:
                return set[1] * set[2] / set[3];
            case 1:
                return set[3] * set[0] / set[2];
            case 2:
                return set[3] * set[0] / set[1];
            case 3:
                return set[1] * set[2] / set[0];
        }
        return -1;
    }

    private static double calculate(double[] set) {
        return set[0] * set[1] / set[2];
    }

    private static int getUnknown(double[] set) {
        for (int i = 0; i < 3; i++)
            if (set[i] < 0)
                return i;
        return -1;
    }

    public static double ideal(GasData values) {
        int i = values.getMissing();
        double[] stuff = values.getValues();
        if (i == 5)
            return -1;
        switch (i) {
            case 0:
                return stuff[3] * stuff[2] / stuff[1] * R;
            case 1:
                return stuff[3] * stuff[2] / stuff[0] * R;
            case 2:
                return stuff[0] * stuff[1] / stuff[3] / R;
            case 3:
                return stuff[0] * stuff[1] / stuff[2] / R;
        }
        return -1;
    }

    /**
     * @param values  The values to be used.
     * @param values2 The values to be used (if you want combined gas law)
     * @return The result of the gas laws
     */

    public static double determine(GasData values, GasData values2) {
        if (values2 == null && values != null)
            return ideal(values);
        if (values2 != null && values == null)
            return ideal(values2);
        return combined(values, values2);
    }

    public static double convertPressure(double initial, String units) {
        if (units.equals("kPa"))
            return initial / 101.325;
        else if (units.equals("Torr"))
            return initial / 760;
        else if (units.equals("psi"))
            return initial / 14.695949;
        return initial;
    }

    public static double convertVolume(double initial, String units) {
        if (units.equals("mL"))
            return initial / 1000;
        else if (units.equals("L"))
            return initial;
        else if (units.charAt(0) == 'c')
            return initial / 1000;
        return initial * 1000;
    }

    public static double convertTemperature(double initial, String units) {
        if (units.equals("C"))
            return initial + 273.15;
        else if (units.equals("F"))
            return 5.0 / 9 * (initial - 32) + 273.15;
        return initial;
    }

    public static double convertBackPressure(double initial, String units) {
        if (units.equals("kPa"))
            return initial * 101.325;
        else if (units.equals("Torr"))
            return initial * 760;
        else if (units.equals("psi"))
            return initial * 14.695949;
        return initial;
    }

    public static double convertBackVolume(double initial, String units) {
        if (units.equals("mL"))
            return initial * 1000;
        else if (units.equals("L"))
            return initial;
        else if (units.charAt(0) == 'c')
            return initial * 1000;
        return initial / 1000;
    }

    public static double convertBackTemperature(double initial, String units) {
        if (units.equals("C"))
            return initial - 273.15;
        else if (units.equals("F"))
            return 1.8 * (initial - 273.15) + 32;
        return initial;
    }
}
